Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Collections.Generic
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Media.Imaging
Imports System.Windows.Navigation
Imports System.Windows.Shapes
Imports OMANE.Common.UI
Imports ICSharpCode.AvalonEdit.Highlighting
Imports System.CodeDom.Compiler
Imports System.Linq.Expressions
Imports System.Data
Imports OMANE.Modules.Builder.MSFunctions
Imports OMANE.Modules.Builder.MSExpression
Imports ICSharpCode.AvalonEdit.CodeCompletion
Imports System.ComponentModel

Public NotInheritable Class MSFunctions

    Public Shared Function Sum(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "SUM({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Sum(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "SUM({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Mean(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "AVG({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Mean(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "AVG({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Var(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "VAR({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Var(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "VAR({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function StDev(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "STDEV({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function StDev(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "STDEV({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Min(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "MIN({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Min(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "MIN({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Max(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "MAX({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Max(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.FuncStr = "MAX({0})"
        result.Sources = source.Sources.Clone()
        result.Parameters = New Func(Of String)() {source.func}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Count(ByVal source As MSProperty) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "COUNT({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Count(ByVal source As MSExpression) As MSExpression
        Dim result As New MSExpression
        result.Sources = source.Sources.Clone()
        result.FuncStr = "COUNT({0})"
        result.Parameters = New Func(Of String)() {source.ResultFunctStr}
        result.IsAggregate = True
        Return result
    End Function
    Public Shared Function Count() As MSExpression
        Dim result As New MSExpression
        result.Sources = New MSTable() {}
        result.FuncStr = "COUNT(*)"
        result.Parameters = New Func(Of String)() {}
        result.IsAggregate = True
        Return result
    End Function


    Public Shared Function Pair(Of K, V)(ByVal key As K, ByVal value As V) As KeyValuePair(Of K, V)
        Return New KeyValuePair(Of K, V)(key, value)
    End Function
    Public Shared Function Map(Of K, V)(ByVal ParamArray kp() As KeyValuePair(Of K, V)) As Dictionary(Of K, V)
        Dim result As New Dictionary(Of K, V)(kp.Length)
        For Each e In kp
            result.Add(e.Key, e.Value)
        Next
        Return result
    End Function
    
    Public Function Vector(Of T As Structure)(ByVal ParamArray data() As T) As Vector(Of T)
        Return New Vector(Of T)(data)
    End Function
    Public Function Vector(Of T As Structure)(ByVal count As Integer, ByVal func As Func(Of T)) As Vector(Of T)
        Return New Vector(Of T)((From i In Enumerable.Range(0, count) Select func.Invoke()).ToArray())
    End Function
    Public Function Vector(Of T As Structure)(ByVal count As Integer, ByVal func As Func(Of Integer, T)) As Vector(Of T)
        Return New Vector(Of T)((From i In Enumerable.Range(0, count) Select func.Invoke(i)).ToArray())
    End Function
    Public Function Vector(Of T As Structure)(ByVal count As Integer, ByVal func As Func(Of Integer, Integer, T)) As Vector(Of T)
        Return New Vector(Of T)((From i In Enumerable.Range(0, count) Select func.Invoke(i, count)).ToArray())
    End Function

    Public Function Vector(Of T As Structure)(ByVal first As T, ByVal func As Func(Of T, T)) As Vector(Of T)

    End Function
    Public Function Vector(Of T As Structure)(ByVal first As T, ByVal func As Func(Of T, Integer, T)) As Vector(Of T)

    End Function
    Public Function Vector(Of T As Structure)(ByVal first As T, ByVal func As Func(Of T, Integer, Integer, T)) As Vector(Of T)

    End Function

End Class

Public Class BaseType

End Class

Public Class TypeBuilder

    Public Shared Function FromColumns(ByVal cols As DataColumn()) As Type

        Dim ass = AppDomain.CurrentDomain.DefineDynamicAssembly( _
            New AssemblyName("temp"), _
            AssemblyBuilderAccess.RunAndCollect)

        Dim mdle = ass.DefineDynamicModule("defaultmodule")

        Dim type = mdle.DefineType("TypeRow", _
            TypeAttributes.Class Or _
            TypeAttributes.Public Or _
            TypeAttributes.Sealed Or _
             TypeAttributes.Serializable, _
             GetType(BaseType))



        For Each c In cols
            Dim cf = type.DefineField("field_" & c.ColumnName, c.DataType, FieldAttributes.Private)

            Dim cp = type.DefineProperty(c.ColumnName, _
                Reflection.PropertyAttributes.HasDefault, c.DataType, Nothing)


        Next

        Return type.CreateType()
    End Function
End Class
